package com.ssy.lingxi.after.sale.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.group.GroupBy;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.after.sale.api.model.constant.AgentFlagEnum;
import com.ssy.lingxi.after.sale.api.model.vo.request.VerifyVO;
import com.ssy.lingxi.after.sale.constant.Constants;
import com.ssy.lingxi.after.sale.entity.*;
import com.ssy.lingxi.after.sale.model.bo.EvaluateBO;
import com.ssy.lingxi.after.sale.model.constant.*;
import com.ssy.lingxi.after.sale.model.vo.request.*;
import com.ssy.lingxi.after.sale.model.vo.response.*;
import com.ssy.lingxi.after.sale.repository.*;
import com.ssy.lingxi.after.sale.service.*;
import com.ssy.lingxi.after.sale.utils.CodeUtils;
import com.ssy.lingxi.after.sale.utils.ParamVerifyUtils;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.constant.order.OrderTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberFeignAfterSaleCommentVO;
import com.ssy.lingxi.message.api.constant.MessageTemplateCode;
import com.ssy.lingxi.message.api.vo.request.SystemMessageRequest;
import com.ssy.lingxi.order.api.model.vo.request.OrderAfterSaleVO;
import com.ssy.lingxi.order.api.model.vo.request.OrderProductAfterSaleVO;
import com.ssy.lingxi.order.api.model.vo.request.OrderProductIdFeignVO;
import com.ssy.lingxi.order.api.model.vo.response.OrderAfterSaleProductFeignDetailVO;
import com.ssy.lingxi.report.api.enums.AfterSaleRepairApplyOperateTypeEnum;
import com.ssy.lingxi.report.api.enums.AfterSaleRepairHandleOperateTypeEnum;
import com.ssy.lingxi.report.api.enums.OperateDataSourceEnum;
import com.ssy.lingxi.report.api.vo.request.OperateNoticeVO;
import com.ssy.lingxi.workflow.api.model.contant.ProcessEnum;
import com.ssy.lingxi.workflow.api.model.vo.request.TaskExecuteVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleTaskCompleteVO;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 售后维修接口服务实现
 * @author 伍将
 * @date 2020/9/1
 * @version 2.0.0
 */
@Service
public class RepairGoodsServiceImpl implements IRepairGoodsService {

    @Resource
    private RepairGoodsRepository repairGoodsRepository;

    @Resource
    private EvaluateRepository evaluateRepository;

    @Resource
    private OuterWorkflowRecordRepository outerWorkflowRecordRepository;

    @Resource
    private InnerWorkflowRecordRepository innerWorkflowRecordRepository;

    @Resource
    private IEvaluateService evaluateService;

    @Resource
    private IInnerWorkflowRecordService innerWorkflowRecordService;

    @Resource
    private IOuterWorkflowRecordService outerWorkflowRecordService;

    @Resource
    private RepairGoodsDetailRepository repairGoodsDetailRepository;
    @Resource
    private RepairGoodsDetailMaterielRepository repairGoodsDetailMaterielRepository;

    @Resource
    private IFeignService feignService;
    @Resource
    private JPAQueryFactory jpaQueryFactory;
    @Resource
    private IProcessFeignService processFeignService;
    /**
     * 分页查询维修
     * @author 伍将
     * @date 2020/9/1
     * @param pageVO:
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.common.response.PageData < com.ssy.lingxi.after.sale.entity.RepairApplyDO>>
     **/
    private Wrapper<PageData<RepairGoodsQueryVO>> pageList(RepairGoodsPageByCommonVO pageVO) {

        // step 1: 组装查询条件
        Specification<RepairGoodsDO> spec =  (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if (pageVO.getSupplierSel()) {
                list.add(criteriaBuilder.equal(root.get("parentMemberId").as(Long.class), pageVO.getParentMemberId()));
                list.add(criteriaBuilder.equal(root.get("parentMemberRoleId").as(Long.class), pageVO.getParentMemberRoleId()));
                list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("outerStatus").as(Integer.class), RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode()));
            } else {
                list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), pageVO.getMemberId()));
                list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), pageVO.getRoleId()));
            }
            if (pageVO.getOuterStatus() != null
                    && !pageVO.getOuterStatus().equals(RepairGoodsOuterStatusEnum.ALL.getCode())) {
                list.add(criteriaBuilder.equal(root.get("outerStatus").as(Integer.class), pageVO.getOuterStatus()));
            }
            if (pageVO.getInnerStatus() != null
                    && !pageVO.getInnerStatus().equals(RepairGoodsInnerStatusEnum.ALL.getCode())) {
                list.add(criteriaBuilder.equal(root.get("innerStatus").as(Integer.class), pageVO.getInnerStatus()));
            }
            if (StringUtils.hasLength(pageVO.getStartTime())) {
                list.add(criteriaBuilder.greaterThan(root.get("applyTime").as(Long.class), DateUtil.parse(pageVO.getStartTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getEndTime())) {
                list.add(criteriaBuilder.lessThan(root.get("applyTime").as(Long.class), DateUtil.parse(pageVO.getEndTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getApplyNo())) {
                list.add(criteriaBuilder.like(root.get("applyNo").as(String.class), "%" + pageVO.getApplyNo().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getApplyAbstract())) {
                list.add(criteriaBuilder.like(root.get("applyAbstract").as(String.class), "%" + pageVO.getApplyAbstract().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getConsumerName())) {
                list.add(criteriaBuilder.like(root.get("consumerName").as(String.class), "%" + pageVO.getConsumerName().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getSupplierName())) {
                list.add(criteriaBuilder.like(root.get("supplierName").as(String.class), "%" + pageVO.getSupplierName().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // step 2: 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("applyTime").descending());

        // step 3: 分页查询数据
        Page<RepairGoodsDO> result = this.repairGoodsRepository.findAll(spec, page);

        // step 4: 组装返回数据
        List<RepairGoodsQueryVO> resultList = convertRepairApplyQueryVO(result.getContent(), pageVO.getSupplierSel());

        return Wrapper.success(new PageData<>(result.getTotalElements(), resultList));
    }

    /**
     * 转换维修查询VO
     * @author 伍将
     * @date 2020/9/1
     * @param repairGoodsDOList:
     * @return : java.util.List<com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyQueryVO>
     **/
    private List<RepairGoodsQueryVO> convertRepairApplyQueryVO(List<RepairGoodsDO> repairGoodsDOList, Boolean isSupplier) {
        List<RepairGoodsQueryVO> resultList = null;
        if (repairGoodsDOList != null) {
            resultList = repairGoodsDOList.stream().map(r -> {
                RepairGoodsQueryVO queryVO = new RepairGoodsQueryVO();
                queryVO.setApplyId(r.getId());
                queryVO.setApplyNo(r.getApplyNo());
                queryVO.setApplyAbstract(r.getApplyAbstract());
                queryVO.setConsumerName(r.getConsumerName());
                queryVO.setSupplierName(r.getSupplierName());
                queryVO.setApplyTime(DateUtil.format(DateUtil.date(r.getApplyTime()), "yyyy-MM-dd HH:mm"));
                queryVO.setInnerStatus(r.getInnerStatus());
                if (!isSupplier && r.getOuterStatus().equals(RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode())) {
                    queryVO.setInnerStatusName("已提交");
                } else {
                    queryVO.setInnerStatusName(RepairGoodsInnerStatusEnum.getDescribe(r.getInnerStatus(), isSupplier));
                }
                queryVO.setOuterStatus(r.getOuterStatus());
                queryVO.setOuterStatusName(RepairGoodsOuterStatusEnum.getMessage(r.getOuterStatus()));

                return queryVO;
            }).collect(Collectors.toList());
        }

        return resultList;
    }

    /**
     * 消费者分页查询维修
     * @author 伍将
     * @date 2020/9/1
     * @param user: 当前登录用户
     * @param pageByConsumeVO:
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.common.response.PageData < com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyQueryVO>>
     **/
    @Override
    public Wrapper<PageData<RepairGoodsQueryVO>> pageByConsumer(UserLoginCacheDTO user, RepairGoodsPageByConsumerVO pageByConsumeVO) {

        RepairGoodsPageByCommonVO pageVO = new RepairGoodsPageByCommonVO();
        pageVO.setCurrent(pageByConsumeVO.getCurrent());
        pageVO.setPageSize(pageByConsumeVO.getPageSize());
        pageVO.setSupplierSel(false);
        pageVO.setMemberId(user.getMemberId());
        pageVO.setRoleId(user.getMemberRoleId());
        pageVO.setApplyNo(pageByConsumeVO.getApplyNo());
        pageVO.setApplyAbstract(pageByConsumeVO.getApplyAbstract());
        pageVO.setStartTime(pageByConsumeVO.getStartTime());
        pageVO.setEndTime(pageByConsumeVO.getEndTime());
        pageVO.setInnerStatus(pageByConsumeVO.getInnerStatus());
        pageVO.setOuterStatus(pageByConsumeVO.getOuterStatus());
        pageVO.setSupplierName(pageByConsumeVO.getSupplierName());

        return pageList(pageVO);
    }

    @Override
    public Wrapper<PageData<RepairGoodsQueryAppVO>> pageAppByConsumer(UserLoginCacheDTO user, RepairGoodsPageAppByConsumerVO pageVO) {
        QRepairGoodsDO replaceDO=QRepairGoodsDO.repairGoodsDO;
        QRepairGoodsDetailDO goodsDetailDO=QRepairGoodsDetailDO.repairGoodsDetailDO;

        //Step 1: 定义关联关系，OrderDO表必须要有distinct()
        JPAQuery<?> query = jpaQueryFactory.from(replaceDO).distinct()
                .leftJoin(goodsDetailDO).on(replaceDO.id.eq(goodsDetailDO.repairId))
                .where(replaceDO.memberId.eq(user.getMemberId()).and(replaceDO.roleId.eq(user.getMemberRoleId())));
        //外部状态
        if(pageVO.getOuterStatus()!=null) {
            query.where(replaceDO.outerStatus.eq(pageVO.getOuterStatus()));
        }
        //内部状态
        if(pageVO.getInnerStatus()!=null) {
            query.where(replaceDO.innerStatus.eq(pageVO.getInnerStatus()));
        }
        //申请时间
        if (StringUtils.hasLength(pageVO.getStartTime())) {
            query.where(replaceDO.applyTime.goe(DateUtil.parse(pageVO.getStartTime()).getTime()));
        }
        if (StringUtils.hasLength(pageVO.getEndTime())) {
            DateTime endOfDay = DateUtil.endOfDay(DateUtil.parse(pageVO.getEndTime()));
            query.where(replaceDO.applyTime.loe(endOfDay.getTime()));
        }
        //关键词
        if (StringUtils.hasLength(pageVO.getKeyword())) {
            query.where(goodsDetailDO.productName.like("%" +pageVO.getKeyword() +"%").or(goodsDetailDO.orderNo.like("%" +pageVO.getKeyword() +"%")).or(replaceDO.applyNo.like("%" +pageVO.getKeyword() +"%")));
        }
        //Step 4: 倒序排序、分页、总数
        query.orderBy(replaceDO.id.desc());
        query.limit(pageVO.getPageSize()).offset(pageVO.getCurrentOffset());
        long totalCount = query.fetchCount();

        //Step 1: 使用transform()对结果进行聚合统计，并通过Projections.Constructor到VO对象
        Map<Long, RepairGoodsQueryAppVO> transform = query.transform(GroupBy.groupBy(replaceDO.id).as(
                Projections.constructor(RepairGoodsQueryAppVO.class, replaceDO.id, replaceDO.applyNo, replaceDO.innerStatus, replaceDO.outerStatus, replaceDO.shopId, replaceDO.shopLogo, replaceDO.shopName)));
        //Step 2:查询商品图片
        List<RepairGoodsDetailDO> goodsDetailDOS = repairGoodsDetailRepository.findByRepairIdIn(transform.keySet());
        if(CollectionUtil.isNotEmpty(goodsDetailDOS)){
            goodsDetailDOS.forEach(o ->{
                RepairGoodsQueryAppVO repairGoodsQueryAppVO = transform.get(o.getRepairId());
                if(repairGoodsQueryAppVO!=null){
                    repairGoodsQueryAppVO.setOuterStatusName(RepairGoodsOuterStatusEnum.getMessage(repairGoodsQueryAppVO.getOuterStatus()));
                    repairGoodsQueryAppVO.setInnerStatusName(RepairGoodsInnerStatusEnum.getMessage(repairGoodsQueryAppVO.getInnerStatus()));
                    List<RepairGoodsQueryProductAppVO> productList = repairGoodsQueryAppVO.getProductList();
                    if(productList==null){
                        productList=new ArrayList<>();
                        repairGoodsQueryAppVO.setProductList(productList);
                    }
                    RepairGoodsQueryProductAppVO vo=new RepairGoodsQueryProductAppVO();
                    BeanUtils.copyProperties(o,vo);
                    productList.add(vo);
                }
            });
        }
        return Wrapper.success(new PageData<>(totalCount, new ArrayList<>(transform.values())));
    }

    @Override
    public Wrapper<PageData<AfterSaleGoodsIMQueryVO>> pageByIM(UserLoginCacheDTO user, AfterSaleGoodsIMPageVO request) {
        // 查询表实体
        QRepairGoodsDO repairGoodsDO = QRepairGoodsDO.repairGoodsDO;
        // 查询条件构造
        BooleanBuilder predicates = new BooleanBuilder();
        Long memberId,roleId,parentMemberId,parentMemberRoleId;
        if(RoleTypeEnum.SERVICE_PROVIDER.getCode().equals(user.getMemberRoleType())){
            memberId=request.getMemberId();
            roleId  =request.getMemberRoleId();
            parentMemberId=user.getMemberId();
            parentMemberRoleId=user.getMemberRoleId();
        }else{
            memberId=user.getMemberId();
            roleId  =user.getMemberRoleId();
            parentMemberId=request.getMemberId();
            parentMemberRoleId=request.getMemberRoleId();
        }
        predicates.and(repairGoodsDO.memberId.eq(memberId));
        if(roleId!=null&&roleId>0){
            predicates.and(repairGoodsDO.roleId.eq(roleId));
        }
        predicates.and(repairGoodsDO.parentMemberId.eq(parentMemberId));
        if(parentMemberRoleId!=null&&parentMemberRoleId>0) {
            predicates.and(repairGoodsDO.parentMemberRoleId.eq(parentMemberRoleId));
        }
        if (StringUtils.hasLength(request.getApplyNo())) {
            predicates.and(repairGoodsDO.applyNo.eq(request.getApplyNo()));
        }
        if (StringUtils.hasLength(request.getApplyAbstract())) {
            predicates.and(repairGoodsDO.applyAbstract.like("%"+request.getApplyAbstract()+"%"));
        }
        if (Objects.nonNull(request.getStartTime())) {
            predicates.and(repairGoodsDO.createTime.goe(request.getStartTime()));
        }
        if (Objects.nonNull(request.getEndTime())) {
            predicates.and(repairGoodsDO.createTime.loe(request.getEndTime()));
        }

        JPAQuery<AfterSaleGoodsIMQueryVO> query = jpaQueryFactory
                .select(Projections.bean(AfterSaleGoodsIMQueryVO.class,
                        repairGoodsDO.applyNo,
                        repairGoodsDO.applyAbstract,
                        repairGoodsDO.createTime.as("applyTime"),
                        repairGoodsDO.outerStatus.as("status"),
                        repairGoodsDO.orderType)
                )
                .from(repairGoodsDO)
                .where(predicates);

        long totalCount = query.fetchCount();
        List<AfterSaleGoodsIMQueryVO> responses = query.orderBy(repairGoodsDO.createTime.desc())
                .offset(request.getCurrentOffset())
                .limit(request.getPageSize())
                .fetch();
        if(CollectionUtil.isNotEmpty(responses)){
            responses.forEach(o ->{
                o.setStatusName(RepairGoodsOuterStatusEnum.getMessage(o.getStatus()));
                o.setApplyTypeName(AfterSaleTypeEnum.REPAIR.getMessage());
                o.setOrderTypeName(OrderTypeEnum.getNameByCode(o.getOrderType()));
            });
        }
        return Wrapper.success(new PageData<>(totalCount, responses));
    }

    /**
     * 消费者分页查询等待提交的维修
     * @author 伍将
     * @date 2020/9/1
     * @param user:
     * @param pageVO:
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.common.response.PageData < com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyQueryVO>>
     **/
    @Override
    public Wrapper<PageData<RepairGoodsQueryVO>> pageToBeSubmitByConsumer(UserLoginCacheDTO user, RepairGoodsPageByConsumerVO pageVO) {

        // step 1: 组装查询条件
        Specification<RepairGoodsDO> spec =  (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), user.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), user.getMemberRoleId()));

            // 查询外部状态为待提交或不接受申请的
            List<Integer> outerStatusList = new ArrayList<>();
            outerStatusList.add(RepairGoodsOuterStatusEnum.TO_BE_SUBMIT.getCode());
            outerStatusList.add(RepairGoodsOuterStatusEnum.UN_ACCEPT_APPLY.getCode());
            list.add(criteriaBuilder.in(root.get("outerStatus")).value(outerStatusList));

            if (StringUtils.hasLength(pageVO.getStartTime())) {
                list.add(criteriaBuilder.greaterThan(root.get("applyTime").as(Long.class), DateUtil.parse(pageVO.getStartTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getEndTime())) {
                list.add(criteriaBuilder.lessThan(root.get("applyTime").as(Long.class), DateUtil.parse(pageVO.getEndTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getApplyNo())) {
                list.add(criteriaBuilder.like(root.get("applyNo").as(String.class), "%" + pageVO.getApplyNo().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getApplyAbstract())) {
                list.add(criteriaBuilder.like(root.get("applyAbstract").as(String.class), "%" + pageVO.getApplyAbstract().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getSupplierName())) {
                list.add(criteriaBuilder.like(root.get("supplierName").as(String.class), "%" + pageVO.getSupplierName().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // step 2: 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("applyTime").descending());

        // step 3: 分页查询数据
        Page<RepairGoodsDO> result = this.repairGoodsRepository.findAll(spec, page);

        // step 4: 组装返回数据
        List<RepairGoodsQueryVO> resultList = convertRepairApplyQueryVO(result.getContent(), false);

        return Wrapper.success(new PageData<>(result.getTotalElements(), resultList));
    }

    /**
     * 消费者分页查询等待确认完成的维修
     * @author 伍将
     * @date 2020/9/1
     * @param user: 当前登录用户
     * @param pageByConsumeVO: 
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.common.response.PageData < com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyQueryVO>>
     **/
    @Override
    public Wrapper<PageData<RepairGoodsQueryVO>> pageToBeConfirmComplete(UserLoginCacheDTO user, RepairGoodsPageByConsumerVO pageByConsumeVO) {
        RepairGoodsPageByCommonVO pageVO = new RepairGoodsPageByCommonVO();
        pageVO.setCurrent(pageByConsumeVO.getCurrent());
        pageVO.setPageSize(pageByConsumeVO.getPageSize());
        pageVO.setSupplierSel(false);
        pageVO.setMemberId(user.getMemberId());
        pageVO.setRoleId(user.getMemberRoleId());
        pageVO.setApplyNo(pageByConsumeVO.getApplyNo());
        pageVO.setApplyAbstract(pageByConsumeVO.getApplyAbstract());
        pageVO.setStartTime(pageByConsumeVO.getStartTime());
        pageVO.setEndTime(pageByConsumeVO.getEndTime());
        pageVO.setInnerStatus(RepairGoodsInnerStatusEnum.CONFIRM_ACCEPT_APPLY.getCode());
        pageVO.setOuterStatus(RepairGoodsOuterStatusEnum.ACCEPT_APPLY.getCode());
        pageVO.setSupplierName(pageByConsumeVO.getSupplierName());

        return pageList(pageVO);
    }

    /**
     * 校验订单-商品退货数量
     * @param saveVO 保存数据
     */
    private void checkRepairGoodsNum(RepairGoodsSaveVO saveVO){
        //构建请求参数
        List<OrderProductIdFeignVO> request = saveVO.getRepairGoodsList().stream().map(o -> {
            OrderProductIdFeignVO vo = new OrderProductIdFeignVO();
            vo.setOrderProductId(o.getOrderRecordId());
            return vo;
        }).collect(Collectors.toList());
        //获取订单商品信息
        Wrapper<List<OrderAfterSaleProductFeignDetailVO>> listWrapper = feignService.afterSalesListById(request);
        if (listWrapper == null || listWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            throw new BusinessException(ResponseCode.BUSINESS_ERROR);
        }
        List<OrderAfterSaleProductFeignDetailVO> data = listWrapper.getData();
        if(CollectionUtil.isEmpty(data)){
            throw new BusinessException(ResponseCode.AS_RETURN_GOODS_PARAM_ERROR);
        }
        Map<Long, OrderAfterSaleProductFeignDetailVO> orderGoodsMap = data.stream().collect(Collectors.toMap(OrderAfterSaleProductFeignDetailVO::getOrderProductId, v -> v));
        for(RepairGoodsDetailSaveVO goodsDetailSaveVO: saveVO.getRepairGoodsList()){
            OrderAfterSaleProductFeignDetailVO orderGood = orderGoodsMap.get(goodsDetailSaveVO.getOrderRecordId());
            if(orderGood==null){
                throw new BusinessException(ResponseCode.AS_REPAIR_GOODS_PARAM_ERROR);
            }
            BigDecimal returnCount = orderGood.getReturnCount() != null ? orderGood.getReturnCount() : BigDecimal.ZERO;
            if(goodsDetailSaveVO.getRepairCount()>(NumberUtil.sub(orderGood.getQuantity(),returnCount).doubleValue())){
                String msg = String.format(ResponseCode.AS_REPAIR_GOODS_PRODUCT_COUNT_PARAM_ERROR.getMessage(), goodsDetailSaveVO.getOrderNo());
                throw new BusinessException(ResponseCode.AS_REPAIR_GOODS_PRODUCT_COUNT_PARAM_ERROR,msg);
            }
        }
    }

    /**
     * 保存维修
     * @author 伍将
     * @date 2020/9/1
     * @param user: 当前登录用户
     * @param saveVO: 保存信息
     * @return : com.ssy.lingxi.common.response.Wrapper<java.lang.Long>
     **/
    @Transactional
    @Override
    public Wrapper<Long> save(UserLoginCacheDTO user, RepairGoodsSaveVO saveVO) {

        // 验证维修参数
        for (RepairGoodsDetailSaveVO item : saveVO.getRepairGoodsList()) {
            // 换货数量不能大于采购数量
            if (item.getRepairCount() > item.getPurchaseCount()) {
                throw new BusinessException(ResponseCode.AS_REPAIR_GOODS_REPAIR_COUNT_ERROR);
            }
        }
        //增加数量校验（如果已经全退，则不能申请维修）
        checkRepairGoodsNum(saveVO);

        // 采购会员、供应商，选中订单校验
        //checkPurchaseAndSupplyByOrderIds(user, saveVO);

        List<OrderProductUpdateFeignVO> updateOrderList = new ArrayList<>();
        // 参数校验
        RepairGoodsDO repairGoodsDO;
        // 如果申请id为空或等于0，则表示新增
        if (saveVO.getRepairId() == null || saveVO.getRepairId() <= 0) {
            // 新增一个申请  组装DO对象
            repairGoodsDO = convertAddRepairDO(user, saveVO);
        }
        // 更新
        else {

            // 如果当前申请是不接受申请，则删除当前申请，并重新新增一个申请
            RepairGoodsDO oldRepairGoodsDO = repairGoodsRepository.findById(saveVO.getRepairId()).orElse(null);
            if (oldRepairGoodsDO == null) {
                throw new BusinessException(ResponseCode.AS_REPAIR_NOT_EXIST);
            }

            List<RepairGoodsDetailDO> goodsDetailDOs = repairGoodsDetailRepository.findByRepairId(oldRepairGoodsDO.getId());
            // 记录需要还原的商品数量
            goodsDetailDOs.forEach(r -> {
                OrderProductUpdateFeignVO entity = new OrderProductUpdateFeignVO();
                entity.setId(r.getOrderRecordId());
                entity.setOrderId(r.getOrderId());
                entity.setRepairCount(-r.getRepairCount());
                updateOrderList.add(entity);
            });

            // 如果上次申请为不接受申请，此时删除该申请再新增一个新申请
            if (oldRepairGoodsDO.getOuterStatus().equals(RepairGoodsOuterStatusEnum.UN_ACCEPT_APPLY.getCode())) {
                // 把旧申请删除
                repairGoodsRepository.deleteById(oldRepairGoodsDO.getId());

                // 新增一个申请  组装DO对象
                repairGoodsDO = convertAddRepairDO(user, saveVO);
            } else {
                repairGoodsDO = oldRepairGoodsDO;
                // 非待提交状态不允许修改数据
                if (!repairGoodsDO.getOuterStatus().equals(RepairGoodsOuterStatusEnum.TO_BE_SUBMIT.getCode())) {
                    throw new BusinessException(ResponseCode.AS_REPAIR_UN_ALLOW_UPDATE);
                }

                repairGoodsDO.setFaultFileList(saveVO.getFaultFileList());
                repairGoodsDO.setApplyAbstract(saveVO.getApplyAbstract());
                repairGoodsDO.setRepairAddress(saveVO.getRepairAddress());
                repairGoodsDO.setUpdateTime(System.currentTimeMillis());
                repairGoodsDO.setRepaireReason(saveVO.getRepaireReason());
                repairGoodsDO.setShopId(saveVO.getShopId());
                repairGoodsDO.setShopLogo(saveVO.getShopLogo());
                repairGoodsDO.setShopName(saveVO.getShopName());
            }
        }

        repairGoodsRepository.saveAndFlush(repairGoodsDO);
        // 根据id生成唯一单据号
        repairGoodsDO.setApplyNo(CodeUtils.digits32(Constants.AFTER_SALE_REPLACE_PREFIX, repairGoodsDO.getId(), Constants.AFTER_SALE_ORDER_NO_MAX_LENGTH));
        repairGoodsRepository.saveAndFlush(repairGoodsDO);

        // 删除历史维修货物
        repairGoodsDetailRepository.deleteAllByRepairId(repairGoodsDO.getId());
        boolean contractOrderType = ParamVerifyUtils.isContractOrderType(repairGoodsDO.getOrderType());
        repairGoodsDetailMaterielRepository.deleteAllByRepairId(repairGoodsDO.getId());
        // 组装现有维修货物
        List<RepairGoodsDetailDO> repairGoodsSaveVOList = convertAddGoodsDO(repairGoodsDO.getId(), saveVO.getRepairGoodsList(),contractOrderType);
        if (repairGoodsSaveVOList != null) {
            // 保存维修货物
            repairGoodsDetailRepository.saveAll(repairGoodsSaveVOList);
            //合同订单，保存物料信息
            if(contractOrderType){
                List<RepairGoodsDetailAssociatedDO> repairGoodsDetailAssociatedDOS = repairGoodsSaveVOList.stream().map(o -> {
                    RepairGoodsDetailAssociatedDO materielDO = o.getMaterielDO();
                    materielDO.setRepairDetailId(o.getId());
                    return materielDO;
                }).collect(Collectors.toList());
                repairGoodsDetailMaterielRepository.saveAll(repairGoodsDetailAssociatedDOS);
            }
            // 记录需要更新的商品数量
            repairGoodsSaveVOList.forEach(r -> {
                OrderProductUpdateFeignVO entity = new OrderProductUpdateFeignVO();
                entity.setId(r.getOrderRecordId());
                entity.setOrderId(r.getOrderId());
                // 同一订单商品合并为一条
                OrderProductUpdateFeignVO oldEntity = updateOrderList.stream().filter(o -> o.getId().equals(r.getOrderRecordId())).findFirst().orElse(null);
                if (oldEntity != null) {
                    oldEntity.setRepairCount(oldEntity.getRepairCount() + r.getRepairCount());
                } else {
                    entity.setRepairCount(r.getRepairCount());
                    updateOrderList.add(entity);
                }
            });
        }

        // 新增数据时才继续操作
        if (saveVO.getRepairId() == null || saveVO.getRepairId() <= 0) {
            // 售saveVO后维修申请待提交+1
            OperateNoticeVO noticeVO = new OperateNoticeVO();
            noticeVO.setMemberId(repairGoodsDO.getMemberId());
            noticeVO.setRoleId(repairGoodsDO.getRoleId());
            noticeVO.setDataSource(OperateDataSourceEnum.AFTER_SALE_REPAIR_APPLY.getCode());
            noticeVO.setIncreaseOperateType(AfterSaleRepairApplyOperateTypeEnum.TO_BE_COMMIT.getCode());
            noticeVO.setIncreaseCount(Constants.SYS_OPERATE_NOTICE_COUNT);
            noticeVO.setIncreaseTitle(repairGoodsDO.getApplyAbstract());
            noticeVO.setIncreaseDataId(repairGoodsDO.getId());
            feignService.addSysOperateNotice(noticeVO);
        }

        // 更新售后商品数量
        // 剔除无需更新数据
        List<OrderProductUpdateFeignVO> updateOrderListTemp = updateOrderList.stream().filter(o -> o.getRepairCount() != 0).collect(Collectors.toList());
        if (0 < updateOrderListTemp.size()) {
            List<OrderAfterSaleVO> orderAfterSaleVOS = buildUpdateOrderParamBySave(updateOrderListTemp);
            Wrapper<?> updateOrderWrapper = feignService.orderProductDetailsUpdate(orderAfterSaleVOS);
            if (updateOrderWrapper == null || updateOrderWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
                throw new BusinessException(ResponseCode.AS_UPDATE_REPAIR_GOODS_COUNT_ERROR);
            }
        }

        return Wrapper.success(repairGoodsDO.getId());
    }

//    /**
//     * 校验售后维修申请，填写的采购会员、供应会员，和选中的订单信息是否符合
//     * @param user 采购会员信息
//     * @param saveVO 售后维修信息
//     */
//    private void checkPurchaseAndSupplyByOrderIds(UserLoginCacheDTO user, RepairGoodsSaveVO saveVO) {
//        // 1.构建【远端调用-订单服务-订单会员信息校验接口】请求参数
//        CheckOrderMemberAfterSaleVO request = new CheckOrderMemberAfterSaleVO();
//        request.setBuyerMemberId(user.getMemberId());
//        request.setBuyerRoleId(user.getMemberRoleId());
//        request.setVendorMemberId(saveVO.getSupplierMemberId());
//        request.setVendorRoleId(saveVO.getSupplierRoleId());
//        List<Long> orderIds = saveVO.getRepairGoodsList().stream().map(RepairGoodsDetailSaveVO::getOrderId).distinct().collect(Collectors.toList());
//        request.setOrderIds(orderIds);
//        // 2.远端调用服务
//        Wrapper<Boolean> wrapper = feignService.checkAfterSaleOrderMember(request);
//        if (Optional.ofNullable(wrapper)
//                .map(res ->
//                        res.getCode() != ResponseCode.SUCCESS.getCode() // 不成功
//                                || res.getData()) // 校验失败
//                .orElse(true)) {
//            throw new BusinessException(ResponseCode.AS_REPAIR_GOODS_MEMBER_INFO);
//        }
//
//    }

    private List<OrderAfterSaleVO> buildUpdateOrderParamByDelete(Long repairId){
        List<RepairGoodsDetailDO> goodsDetailDOS = repairGoodsDetailRepository.findByRepairId(repairId);
        Map<Long, List<OrderProductAfterSaleVO>> orderProductMap=new HashMap<>();
        goodsDetailDOS.forEach(r ->{
            List<OrderProductAfterSaleVO> orderProductList = orderProductMap.get(r.getOrderId());
            double repairCount =  -r.getRepairCount();
            if(CollectionUtil.isEmpty(orderProductList)){
                orderProductList=new ArrayList<>();
                OrderProductAfterSaleVO vo=new OrderProductAfterSaleVO();
                vo.setMaintainCount(BigDecimal.valueOf(repairCount));
                vo.setProductId(r.getOrderRecordId());
                orderProductList.add(vo);
                orderProductMap.put(r.getOrderId(),orderProductList);
            }else{
                OrderProductAfterSaleVO vo=new OrderProductAfterSaleVO();
                vo.setMaintainCount(BigDecimal.valueOf(repairCount));
                vo.setProductId(r.getOrderRecordId());
                orderProductList.add(vo);
            }
        });
        return convertOrderProductMapToList(orderProductMap);
    }

    private List<OrderAfterSaleVO> buildUpdateOrderParamBySave(List<OrderProductUpdateFeignVO> orderProducts){
        Map<Long, List<OrderProductAfterSaleVO>> orderProductMap=new HashMap<>();
        orderProducts.forEach(r ->{
            List<OrderProductAfterSaleVO> orderProductList = orderProductMap.get(r.getOrderId());
            if(CollectionUtil.isEmpty(orderProductList)){
                orderProductList=new ArrayList<>();
                OrderProductAfterSaleVO vo=new OrderProductAfterSaleVO();
                vo.setMaintainCount(BigDecimal.valueOf(r.getRepairCount()));
                vo.setProductId(r.getId());
                orderProductList.add(vo);
                orderProductMap.put(r.getOrderId(),orderProductList);
            }else{
                OrderProductAfterSaleVO vo=new OrderProductAfterSaleVO();
                vo.setMaintainCount(BigDecimal.valueOf(r.getRepairCount()));
                vo.setProductId(r.getId());
                orderProductList.add(vo);
            }
        });
        return convertOrderProductMapToList(orderProductMap);
    }

    private List<OrderAfterSaleVO> convertOrderProductMapToList(Map<Long, List<OrderProductAfterSaleVO>> orderProductMap){
        // 更新售后商品数量
        List<OrderAfterSaleVO> afterSales=new ArrayList<>();
        orderProductMap.forEach((k,v)->{
            OrderAfterSaleVO orderVO=new OrderAfterSaleVO();
            orderVO.setOrderId(k);
            orderVO.setProducts(v);
            afterSales.add(orderVO);
        });
        return afterSales;
    }


    /**
     * 组装新增申请DO
     * @author 伍将
     * @date 2020/9/2
     * @param user: 当前登录用户
     * @param saveVO:
     * @return : com.ssy.lingxi.after.sale.entity.RepairApplyDO
     **/
    private RepairGoodsDO convertAddRepairDO(UserLoginCacheDTO user, RepairGoodsSaveVO saveVO) {

        RepairGoodsDO repairGoodsDO = new RepairGoodsDO();
        repairGoodsDO.setApplyNo("-");
        repairGoodsDO.setMemberId(user.getMemberId());
        repairGoodsDO.setRoleId(user.getMemberRoleId());
        repairGoodsDO.setParentMemberId(saveVO.getSupplierMemberId());
        repairGoodsDO.setParentMemberRoleId(saveVO.getSupplierRoleId());
        repairGoodsDO.setConsumerName(user.getCompany());
        repairGoodsDO.setSupplierName(saveVO.getSupplierName());
        repairGoodsDO.setInnerStatus(RepairGoodsInnerStatusEnum.TO_BE_SUBMIT.getCode());
        repairGoodsDO.setOuterStatus(RepairGoodsOuterStatusEnum.TO_BE_SUBMIT.getCode());
        repairGoodsDO.setApplyAbstract(saveVO.getApplyAbstract());
        repairGoodsDO.setRepairAddress(saveVO.getRepairAddress());
        repairGoodsDO.setFaultFileList(saveVO.getFaultFileList());
        repairGoodsDO.setApplyTime(System.currentTimeMillis());
        repairGoodsDO.setCreateTime(System.currentTimeMillis());
        repairGoodsDO.setUpdateTime(0L);
        repairGoodsDO.setOrderType(saveVO.getOrderType());
        repairGoodsDO.setRepaireReason(saveVO.getRepaireReason());
        repairGoodsDO.setShopId(saveVO.getShopId());
        repairGoodsDO.setShopLogo(saveVO.getShopLogo());
        repairGoodsDO.setShopName(saveVO.getShopName());
        // 设置代客
        repairGoodsDO.setAgentFlag(Optional.ofNullable(saveVO.getAgentFlag()).orElse(AgentFlagEnum.NOT.getCode()));
        return repairGoodsDO;
    }

    //校验物料信息
//    private void checkMaterielDO(RepairGoodsDetailAssociatedDO materielDO){
//        if(materielDO==null){return;}
//        if(!StringUtils.hasLength(materielDO.getProductId())){
//            throw new BusinessException(ResponseCode.AS_REPAIR_GOODS_DETAIL_MATERIEL_REQUIRED);
//        }else if(!StringUtils.hasLength(materielDO.getProductName())){
//            throw new BusinessException(ResponseCode.AS_REPAIR_GOODS_DETAIL_MATERIEL_REQUIRED);
//        }
//    }

    /**
     * 组装新增维修货物DO
     * @param repairId 维修id
     * @param goodsList 维修商品
     * @return 维修商品列表
     */
    private List<RepairGoodsDetailDO> convertAddGoodsDO(Long repairId, List<RepairGoodsDetailSaveVO> goodsList,Boolean contractOrderType) {

        List<RepairGoodsDetailDO> resultList = null;
        if (goodsList != null) {
            resultList = goodsList.stream().map(r -> {
                RepairGoodsDetailDO addDo = new RepairGoodsDetailDO();
                addDo.setRepairId(repairId);
                addDo.setOrderId(r.getOrderId());
                addDo.setOrderRecordId(r.getOrderRecordId());
                addDo.setOrderNo(r.getOrderNo());
                addDo.setProductId(r.getProductId());
                addDo.setProductName(r.getProductName());
                addDo.setCategory(r.getCategory());
                addDo.setBrand(r.getBrand());
                addDo.setUnit(r.getUnit());
                addDo.setPurchaseCount(r.getPurchaseCount());
                addDo.setRepairCount(r.getRepairCount());
                addDo.setRepairReason(r.getRepairReason());
                addDo.setIsHasTax(r.getIsHasTax());
                addDo.setTaxRate(r.getTaxRate());
                addDo.setContractId(r.getContractId());
                addDo.setContractNo(r.getContractNo());
                addDo.setType(r.getType());
                addDo.setSkuId(r.getSkuId());
                addDo.setSkuPic(r.getSkuPic());
                if (contractOrderType) {
                    RepairGoodsDetailAssociatedDO materielDO=new RepairGoodsDetailAssociatedDO();
                    materielDO.setRepairId(repairId);
                    materielDO.setProductId(r.getAssociatedProductId());
                    materielDO.setProductName(r.getAssociatedProductName());
                    materielDO.setBrand(r.getAssociatedBrand());
                    materielDO.setCategory(r.getAssociatedCategory());
                    materielDO.setUnit(r.getAssociatedUnit());
                    materielDO.setType(r.getAssociatedType());
                    /*非强关联，可以不[关联报价商品],不再校验 checkMaterielDO(materielDO);*/
                    addDo.setMaterielDO(materielDO);
                }
                return addDo;
            }).collect(Collectors.toList());
        }

        return resultList;
    }

    /**
     * 删除维修
     * @author 伍将
     * @date 2020/9/1
     * @param user: 当前登录用户
     * @param repairId:
     * @return : com.ssy.lingxi.common.response.Wrapper
     **/
    @Override
    public Wrapper<Void> delete(UserLoginCacheDTO user, Long repairId) {

        RepairGoodsDO repairGoodsDO = repairGoodsRepository.findById(repairId).orElse(null);
        if (repairGoodsDO == null) {
            throw new BusinessException(ResponseCode.AS_REPAIR_NOT_EXIST);
        }
        //只有内部状态为：待提交与不接受申请才可以删除
        if (!repairGoodsDO.getOuterStatus().equals(RepairGoodsOuterStatusEnum.TO_BE_SUBMIT.getCode())
                && !repairGoodsDO.getOuterStatus().equals(RepairGoodsOuterStatusEnum.UN_ACCEPT_APPLY.getCode())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_UN_ALLOW_DELETE);
        }

        repairGoodsRepository.deleteById(repairGoodsDO.getId());

//        List<RepairGoodsDetailDO> goodsDetailDOs = repairGoodsDetailRepository.findByRepairId(repairGoodsDO.getId());
//        // 记录需要还原的商品数量
//        List<OrderProductUpdateFeignVO> updateOrderList = goodsDetailDOs.stream().map(r -> {
//            OrderProductUpdateFeignVO entity = new OrderProductUpdateFeignVO();
//            entity.setId(r.getOrderRecordId());
//            entity.setRepairCount(-r.getRepairCount());
//            return entity;
//        }).collect(Collectors.toList());

        // 售后维修申请待提交-1
        OperateNoticeVO noticeVO = new OperateNoticeVO();
        noticeVO.setMemberId(repairGoodsDO.getMemberId());
        noticeVO.setRoleId(repairGoodsDO.getRoleId());
        noticeVO.setDataSource(OperateDataSourceEnum.AFTER_SALE_REPAIR_APPLY.getCode());
        noticeVO.setReduceOperateType(AfterSaleRepairApplyOperateTypeEnum.TO_BE_COMMIT.getCode());
        noticeVO.setReduceCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        noticeVO.setReduceDataId(repairGoodsDO.getId());
        feignService.addSysOperateNotice(noticeVO);

        // 更新售后商品数量
        List<OrderAfterSaleVO> orderAfterSaleVOS = buildUpdateOrderParamByDelete(repairId);
        Wrapper<?> updateOrderWrapper = feignService.orderProductDetailsUpdate(orderAfterSaleVOS);
        if (updateOrderWrapper == null || updateOrderWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            throw new BusinessException(ResponseCode.AS_UPDATE_RETURN_GOODS_COUNT_ERROR);
        }

        return Wrapper.success();
    }

    /**
     * 提交维修
     * @author 伍将
     * @date 2020/9/1
     * @param user: 当前登录用户
     * @param repairId:
     * @return : com.ssy.lingxi.common.response.Wrapper
     **/
    @Transactional
    @Override
    public Wrapper<Void> submit(UserLoginCacheDTO user, Long repairId) {
        RepairGoodsDO repairGoodsDO = repairGoodsRepository.findById(repairId).orElse(null);
        if (repairGoodsDO == null) {
            throw new BusinessException(ResponseCode.AS_REPAIR_NOT_EXIST);
        }
        // 只有待提交状态的申请才允许提交
        if (!RepairGoodsOuterStatusEnum.TO_BE_SUBMIT.getCode().equals(repairGoodsDO.getOuterStatus())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_UN_ALLOW_SUBMIT);
        }

        // 开启工作流
        SimpleTaskCompleteVO taskResultVOWrapper = processFeignService.startSimpleProcess(repairGoodsDO.getMemberId(), repairGoodsDO.getRoleId(), ProcessEnum.AFTER_SALE_REPAIR_INNER_VERIFY.getCode(), repairGoodsDO.getId());
        repairGoodsDO.setTaskId(taskResultVOWrapper.getTaskId());
        repairGoodsDO.setInnerTaskStep(taskResultVOWrapper.getStep());
        repairGoodsDO.setInnerStatus(taskResultVOWrapper.getStatus());

        // 保存申请
        repairGoodsDO.setOuterStatus(RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode());
        repairGoodsDO.setApplyTime(System.currentTimeMillis());
        repairGoodsDO.setUpdateTime(System.currentTimeMillis());
        repairGoodsRepository.saveAndFlush(repairGoodsDO);

        // 新增外部流转记录
        addOuterWorkflowRecord(user, repairId, repairGoodsDO.getOuterStatus(), RepairGoodsOuterStatusEnum.getMessage(repairGoodsDO.getOuterStatus()), RepairGoodsActionEnum.SUBMIT.getMessage(), "");

        // 售后维修申请待提交-1
        OperateNoticeVO noticeVO = new OperateNoticeVO();
        noticeVO.setMemberId(repairGoodsDO.getMemberId());
        noticeVO.setRoleId(repairGoodsDO.getRoleId());
        noticeVO.setDataSource(OperateDataSourceEnum.AFTER_SALE_REPAIR_APPLY.getCode());
        noticeVO.setReduceOperateType(AfterSaleRepairApplyOperateTypeEnum.TO_BE_COMMIT.getCode());
        noticeVO.setReduceCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        noticeVO.setReduceDataId(repairGoodsDO.getId());
        feignService.addSysOperateNotice(noticeVO);

        // 售后维修处理待提交审核维修申请单+1
        noticeVO = new OperateNoticeVO();
        noticeVO.setMemberId(repairGoodsDO.getParentMemberId());
        noticeVO.setRoleId(repairGoodsDO.getParentMemberRoleId());
        noticeVO.setDataSource(OperateDataSourceEnum.AFTER_SALE_REPAIR_HANDLE.getCode());
        noticeVO.setIncreaseOperateType(AfterSaleRepairHandleOperateTypeEnum.TO_BE_VALIFY_COMMIT.getCode());
        noticeVO.setIncreaseCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        noticeVO.setIncreaseTitle(repairGoodsDO.getApplyAbstract());
        noticeVO.setIncreaseDataId(repairGoodsDO.getId());
        feignService.addSysOperateNotice(noticeVO);

        // 新增消息通知
        SystemMessageRequest request = new SystemMessageRequest();
        request.setMemberId(repairGoodsDO.getParentMemberId());
        request.setRoleId(repairGoodsDO.getParentMemberRoleId());
        request.setMessageNotice(MessageTemplateCode.repair_goods_handle_wait_audit);
        List<String> params = new ArrayList<>();
        params.add(repairGoodsDO.getApplyNo());
        params.add(repairGoodsDO.getApplyAbstract());
        params.add(RepairGoodsOuterStatusEnum.getMessage(repairGoodsDO.getOuterStatus()));
        request.setParams(params);
        feignService.sendSystemMessage(request);
        return Wrapper.success();
    }

    /**
     * 新增外部工作流记录
     * @author 伍将
     * @date 2020/12/26
     * @param user: 操作用户
     * @param repairId: 维修id
     * @param status: 当前状态值
     * @param statusName:当前状态对应名称
     * @param operate:操作名称
     * @param opinion: 意见
     **/
    private void addOuterWorkflowRecord(UserLoginCacheDTO user, Long repairId, Integer status, String statusName, String operate, String opinion) {

        OuterWorkflowRecordDO recordDO = new OuterWorkflowRecordDO();
        recordDO.setAfterSaleId(repairId);
        recordDO.setAfterSaleType(AfterSaleTypeEnum.REPAIR.getCode());
        recordDO.setUserId(user.getUserId());
        recordDO.setMemberId(user.getMemberId());
        recordDO.setRoleId(user.getMemberRoleId());
        recordDO.setRoleName(user.getMemberRoleName());
        recordDO.setStatus(statusName);
        recordDO.setStatusCode(status);
        recordDO.setOperate(operate);
        recordDO.setOperateTime(System.currentTimeMillis());
        recordDO.setOpinion(opinion);
        outerWorkflowRecordRepository.saveAndFlush(recordDO);
    }

    /**
     * 确认完成维修
     * @author 伍将
     * @date 2020/9/2
     * @param user: 当前登录用户
     * @param completeVO: 
     * @return : com.ssy.lingxi.common.response.Wrapper
     **/
    @Transactional
    @Override
    public Wrapper<Void> confirmComplete(UserLoginCacheDTO user, RepairGoodsConfirmCompleteVO completeVO) {
        if (completeVO.getEvaluate() == null) {
            throw new BusinessException(ResponseCode.AS_EVALUATE_PARAM_ERROR);
        }
        if (completeVO.getEvaluate().getLevel() < EvaluateLevelEnum.ONE.getCode()
                || completeVO.getEvaluate().getLevel() > EvaluateLevelEnum.FIVE.getCode()) {
            throw new BusinessException(ResponseCode.AS_EVALUATE_LEVEL_ERROR);
        }
        // 当选择2分或1分时，售后评价为必填
        if (completeVO.getEvaluate().getLevel() <= EvaluateLevelEnum.TOW.getCode()) {
            if (!StringUtils.hasLength(completeVO.getEvaluate().getContent())) {
                throw new BusinessException(ResponseCode.AS_EVALUATE_CONTENT_EMPTY);
            }
        }

        RepairGoodsDO repairGoodsDO = repairGoodsRepository.findById(completeVO.getRepairId()).orElse(null);
        if (repairGoodsDO == null) {
            throw new BusinessException(ResponseCode.AS_REPAIR_NOT_EXIST);
        }
        if (!repairGoodsDO.getOuterStatus().equals(RepairGoodsOuterStatusEnum.ACCEPT_APPLY.getCode())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_UN_ALLOW_CONFIRM_COMPLETE);
        }

        // 新增评价
        EvaluateDO evaluateDO = new EvaluateDO();
        evaluateDO.setAfterSaleId(repairGoodsDO.getId());
        evaluateDO.setAfterSaleType(AfterSaleTypeEnum.REPAIR.getCode());
        evaluateDO.setLevel(completeVO.getEvaluate().getLevel());
        evaluateDO.setContent(completeVO.getEvaluate().getContent());
        evaluateDO.setEvaluateTime(System.currentTimeMillis());
        evaluateRepository.saveAndFlush(evaluateDO);

        // 提交后内部状态为已确认售后完成，外部状态为售后完成
        repairGoodsDO.setInnerStatus(RepairGoodsInnerStatusEnum.CONFIRM_COMPLETE.getCode());
        repairGoodsDO.setOuterStatus(RepairGoodsOuterStatusEnum.COMPLETE.getCode());
        repairGoodsRepository.saveAndFlush(repairGoodsDO);

        // 新增外部流转记录
        addOuterWorkflowRecord(user, completeVO.getRepairId(), repairGoodsDO.getOuterStatus(), ReplaceGoodsOuterStatusEnum.COMPLETE.getMessage(), ReturnGoodsActionEnum.CONFIRM_COMPLETE.getMessage(), "");

        // 完成售后之后调用内部评价接口
        MemberFeignAfterSaleCommentVO commentVO = new MemberFeignAfterSaleCommentVO();
        commentVO.setCommentMemberId(repairGoodsDO.getMemberId());
        commentVO.setCommentRoleId(repairGoodsDO.getRoleId());
        commentVO.setReceivedMemberId(repairGoodsDO.getParentMemberId());
        commentVO.setReceivedRoleId(repairGoodsDO.getParentMemberRoleId());
        commentVO.setAfterSaleTime(DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
        commentVO.setStar(evaluateDO.getLevel());
        commentVO.setComment(evaluateDO.getContent());
        commentVO.setOrderNo(repairGoodsDO.getApplyNo());
        List<RepairGoodsDetailDO> detailDos = repairGoodsDetailRepository.findByRepairId(repairGoodsDO.getId());
        StringBuilder productStr = new StringBuilder();
        for (RepairGoodsDetailDO detail : detailDos) {
            productStr.append(RepairGoodsHelpEnum.PRODUCT.getMessage()).append(detail.getProductName()).append("\n");
            productStr.append(RepairGoodsHelpEnum.PROCESSING_QUANTITY.getMessage()).append(detail.getRepairCount()).append(detail.getUnit()).append("\n");
        }
        commentVO.setProduct(productStr.toString());
        feignService.addMemberEvaluate(commentVO);

        // 售后维修申请待确认售后完成-1
        OperateNoticeVO noticeVO = new OperateNoticeVO();
        noticeVO.setMemberId(repairGoodsDO.getMemberId());
        noticeVO.setRoleId(repairGoodsDO.getRoleId());
        noticeVO.setDataSource(OperateDataSourceEnum.AFTER_SALE_REPAIR_APPLY.getCode());
        noticeVO.setReduceOperateType(AfterSaleRepairApplyOperateTypeEnum.TO_BE_CONFIRM_COMPLETE.getCode());
        noticeVO.setReduceCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        noticeVO.setReduceDataId(repairGoodsDO.getId());
        feignService.addSysOperateNotice(noticeVO);

        return Wrapper.success();
    }

    /**
     * 供应商分页查询维修
     * @author 伍将
     * @date 2020/9/2
     * @param user: 当前登录用户
     * @param pageBySupplierVO:
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.common.response.PageData < com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyQueryVO>>
     **/
    @Override
    public Wrapper<PageData<RepairGoodsQueryVO>> pageBySupplier(UserLoginCacheDTO user, RepairGoodsPageBySupplierVO pageBySupplierVO) {

        RepairGoodsPageByCommonVO pageVO = new RepairGoodsPageByCommonVO();
        pageVO.setCurrent(pageBySupplierVO.getCurrent());
        pageVO.setPageSize(pageBySupplierVO.getPageSize());
        pageVO.setSupplierSel(true);
        pageVO.setParentMemberId(user.getMemberId());
        pageVO.setParentMemberRoleId(user.getMemberRoleId());
        pageVO.setApplyNo(pageBySupplierVO.getApplyNo());
        pageVO.setApplyAbstract(pageBySupplierVO.getApplyAbstract());
        pageVO.setStartTime(pageBySupplierVO.getStartTime());
        pageVO.setEndTime(pageBySupplierVO.getEndTime());
        pageVO.setInnerStatus(pageBySupplierVO.getInnerStatus());
        pageVO.setOuterStatus(pageBySupplierVO.getOuterStatus());
        pageVO.setConsumerName(pageBySupplierVO.getConsumerName());

        return pageList(pageVO);
    }

    /**
     * 供应商分页查询待提交维修
     * @author 伍将
     * @date 2020/9/2
     * @param user: 当前登录用户
     * @param pageBySupplierVO:
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.common.response.PageData < com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyQueryVO>>
     **/
    @Override
    public Wrapper<PageData<RepairGoodsQueryVO>> pageToBeSubmitBySupplier(UserLoginCacheDTO user, RepairGoodsPageBySupplierVO pageBySupplierVO) {

        RepairGoodsPageByCommonVO pageVO = new RepairGoodsPageByCommonVO();
        pageVO.setCurrent(pageBySupplierVO.getCurrent());
        pageVO.setPageSize(pageBySupplierVO.getPageSize());
        pageVO.setSupplierSel(true);
        pageVO.setParentMemberId(user.getMemberId());
        pageVO.setParentMemberRoleId(user.getMemberRoleId());
        pageVO.setApplyNo(pageBySupplierVO.getApplyNo());
        pageVO.setApplyAbstract(pageBySupplierVO.getApplyAbstract());
        pageVO.setStartTime(pageBySupplierVO.getStartTime());
        pageVO.setEndTime(pageBySupplierVO.getEndTime());
        pageVO.setInnerStatus(RepairGoodsInnerStatusEnum.TO_BE_SUBMIT.getCode());
        pageVO.setOuterStatus(RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode());
        pageVO.setConsumerName(pageBySupplierVO.getConsumerName());

        return pageList(pageVO);
    }

    /**
     * 供应商分页查询待审核一级维修
     * @author 伍将
     * @date 2020/9/2
     * @param user: 当前登录用户
     * @param pageBySupplierVO:
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.common.response.PageData < com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyQueryVO>>
     **/
    @Override
    public Wrapper<PageData<RepairGoodsQueryVO>> pageToBeVerifyStepOne(UserLoginCacheDTO user, RepairGoodsPageBySupplierVO pageBySupplierVO) {

        RepairGoodsPageByCommonVO pageVO = new RepairGoodsPageByCommonVO();
        pageVO.setCurrent(pageBySupplierVO.getCurrent());
        pageVO.setPageSize(pageBySupplierVO.getPageSize());
        pageVO.setSupplierSel(true);
        pageVO.setParentMemberId(user.getMemberId());
        pageVO.setParentMemberRoleId(user.getMemberRoleId());
        pageVO.setApplyNo(pageBySupplierVO.getApplyNo());
        pageVO.setApplyAbstract(pageBySupplierVO.getApplyAbstract());
        pageVO.setStartTime(pageBySupplierVO.getStartTime());
        pageVO.setEndTime(pageBySupplierVO.getEndTime());
        pageVO.setInnerStatus(RepairGoodsInnerStatusEnum.SUBMIT_VERIFY_PASSED.getCode());
        pageVO.setOuterStatus(RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode());
        pageVO.setConsumerName(pageBySupplierVO.getConsumerName());

        return pageList(pageVO);
    }

    /**
     * 一级审核
     * @author 伍将
     * @date 2020/10/17
     * @param user: 当前登录用户
     * @param verifyVO:
     * @return : com.ssy.lingxi.common.response.Wrapper
     **/
    @Override
    public Wrapper<Void> verifyStepOne(UserLoginCacheDTO user, VerifyVO verifyVO) {
        // 当选择审核不通过时，审核不通过原因为必填
        if (verifyVO.getIsPass().equals(CommonBooleanEnum.NO.getCode()) && !StringUtils.hasLength(verifyVO.getOpinion())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_VERIFY_OPINION_EMPTY);
        }
        RepairGoodsDO repairGoodsDO = repairGoodsRepository.findById(verifyVO.getApplyId()).orElse(null);
        if (repairGoodsDO == null) {
            throw new BusinessException(ResponseCode.AS_REPAIR_NOT_EXIST);
        }
        // 外部状态不为待确认或者内部状态不为提交审核，不允许审核
        if (!RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode().equals(repairGoodsDO.getOuterStatus())
                || !RepairGoodsInnerStatusEnum.SUBMIT_VERIFY_PASSED.getCode().equals(repairGoodsDO.getInnerStatus())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_UN_ALLOW_VERIFY);
        }

        // 执行工作流
        repairGoodsDO= completeInnerTask(repairGoodsDO, verifyVO.getIsPass());
        repairGoodsRepository.saveAndFlush(repairGoodsDO);

        String statusName = RepairGoodsInnerStatusEnum.getMessage(repairGoodsDO.getInnerStatus());
        // 新增内部流转记录
        addInnerWorkflowRecord(user, repairGoodsDO.getId(), repairGoodsDO.getInnerStatus(), statusName, RepairGoodsActionEnum.EXAMINE_STEP_1.getMessage(), verifyVO.getOpinion());

        // 待审核维修申请单（一级）-1,(待审核维修申请单（二级）+1或待确认维修申请单+1)
        OperateNoticeVO noticeVO = new OperateNoticeVO();
        noticeVO.setMemberId(repairGoodsDO.getParentMemberId());
        noticeVO.setRoleId(repairGoodsDO.getParentMemberRoleId());
        noticeVO.setDataSource(OperateDataSourceEnum.AFTER_SALE_REPAIR_HANDLE.getCode());
        noticeVO.setReduceOperateType(AfterSaleRepairHandleOperateTypeEnum.TO_BE_VALIFY_STEP1.getCode());
        noticeVO.setReduceCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        AfterSaleRepairHandleOperateTypeEnum operateTypeEnum = RepairGoodsInnerStatusEnum.VERIFY_STEP1_UN_PASSED.getCode().equals(repairGoodsDO.getInnerStatus())
                ? AfterSaleRepairHandleOperateTypeEnum.TO_BE_CONFIRM : AfterSaleRepairHandleOperateTypeEnum.TO_BE_VALIFY_STEP2;
        noticeVO.setIncreaseOperateType(operateTypeEnum.getCode());
        noticeVO.setIncreaseCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        noticeVO.setIncreaseTitle(repairGoodsDO.getApplyAbstract());
        noticeVO.setIncreaseDataId(repairGoodsDO.getId());
        noticeVO.setReduceDataId(repairGoodsDO.getId());
        feignService.addSysOperateNotice(noticeVO);

        // 新增消息通知
        SystemMessageRequest request = new SystemMessageRequest();
        request.setMemberId(repairGoodsDO.getParentMemberId());
        request.setRoleId(repairGoodsDO.getParentMemberRoleId());
        String messageTemplateCode = MessageTemplateCode.repair_goods_handle_audit_step_2;
        if (RepairGoodsInnerStatusEnum.VERIFY_STEP1_UN_PASSED.getCode().equals(repairGoodsDO.getInnerStatus())) {
            messageTemplateCode = MessageTemplateCode.repair_goods_handle_confirm;
        }
        request.setMessageNotice(messageTemplateCode);
        List<String> params = new ArrayList<>();
        params.add(repairGoodsDO.getApplyNo());
        params.add(repairGoodsDO.getApplyAbstract());
        params.add(RepairGoodsOuterStatusEnum.getMessage(repairGoodsDO.getOuterStatus()));
        request.setParams(params);
        feignService.sendSystemMessage(request);

        return Wrapper.success();
    }

    /**
     * 供应商分页查询待审核二级维修
     * @author 伍将
     * @date 2020/9/2
     * @param user: 当前登录用户
     * @param pageBySupplierVO:
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.common.response.PageData < com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyQueryVO>>
     **/
    @Override
    public Wrapper<PageData<RepairGoodsQueryVO>> pageToBeVerifyStepTwo(UserLoginCacheDTO user, RepairGoodsPageBySupplierVO pageBySupplierVO) {
        RepairGoodsPageByCommonVO pageVO = new RepairGoodsPageByCommonVO();
        pageVO.setCurrent(pageBySupplierVO.getCurrent());
        pageVO.setPageSize(pageBySupplierVO.getPageSize());
        pageVO.setSupplierSel(true);
        pageVO.setParentMemberId(user.getMemberId());
        pageVO.setParentMemberRoleId(user.getMemberRoleId());
        pageVO.setApplyNo(pageBySupplierVO.getApplyNo());
        pageVO.setApplyAbstract(pageBySupplierVO.getApplyAbstract());
        pageVO.setStartTime(pageBySupplierVO.getStartTime());
        pageVO.setEndTime(pageBySupplierVO.getEndTime());
        pageVO.setInnerStatus(RepairGoodsInnerStatusEnum.VERIFY_STEP1_PASSED.getCode());
        pageVO.setOuterStatus(RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode());
        pageVO.setConsumerName(pageBySupplierVO.getConsumerName());

        return pageList(pageVO);
    }

    /**
     * 二级审核
     * @author 伍将
     * @date 2020/10/17
     * @param user: 当前登录用户
     * @param verifyVO:
     * @return : com.ssy.lingxi.common.response.Wrapper
     **/
    @Override
    public Wrapper<Void> verifyStepTwo(UserLoginCacheDTO user, VerifyVO verifyVO) {
        // 当选择审核不通过时，审核不通过原因为必填
        if (verifyVO.getIsPass().equals(CommonBooleanEnum.NO.getCode()) && !StringUtils.hasLength(verifyVO.getOpinion())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_VERIFY_OPINION_EMPTY);
        }
        RepairGoodsDO repairGoodsDO = repairGoodsRepository.findById(verifyVO.getApplyId()).orElse(null);
        if (repairGoodsDO == null) {
            throw new BusinessException(ResponseCode.AS_REPAIR_NOT_EXIST);
        }
        // 外部状态为待确认，内部状态为一级审核通过时才允许审核
        if (!repairGoodsDO.getOuterStatus().equals(RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode())
                || !repairGoodsDO.getInnerStatus().equals(RepairGoodsInnerStatusEnum.VERIFY_STEP1_PASSED.getCode())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_UN_ALLOW_VERIFY);
        }

        // 执行工作流
        repairGoodsDO= completeInnerTask(repairGoodsDO, verifyVO.getIsPass());
        repairGoodsRepository.saveAndFlush(repairGoodsDO);

        String statusName = RepairGoodsInnerStatusEnum.getMessage(repairGoodsDO.getInnerStatus());
        // 新增内部流转记录
        addInnerWorkflowRecord(user, repairGoodsDO.getId(), repairGoodsDO.getInnerStatus(), statusName, RepairGoodsActionEnum.EXAMINE_STEP_2.getMessage(), verifyVO.getOpinion());

        // 待审核维修申请单（二级）-1,待确认维修申请单+1
        OperateNoticeVO noticeVO = new OperateNoticeVO();
        noticeVO.setMemberId(repairGoodsDO.getParentMemberId());
        noticeVO.setRoleId(repairGoodsDO.getParentMemberRoleId());
        noticeVO.setDataSource(OperateDataSourceEnum.AFTER_SALE_REPAIR_HANDLE.getCode());
        noticeVO.setReduceOperateType(AfterSaleRepairHandleOperateTypeEnum.TO_BE_VALIFY_STEP2.getCode());
        noticeVO.setReduceCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        noticeVO.setIncreaseOperateType(AfterSaleRepairHandleOperateTypeEnum.TO_BE_CONFIRM.getCode());
        noticeVO.setIncreaseCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        noticeVO.setIncreaseTitle(repairGoodsDO.getApplyAbstract());
        noticeVO.setIncreaseDataId(repairGoodsDO.getId());
        noticeVO.setReduceDataId(repairGoodsDO.getId());
        feignService.addSysOperateNotice(noticeVO);

        // 新增消息通知
        SystemMessageRequest request = new SystemMessageRequest();
        request.setMemberId(repairGoodsDO.getParentMemberId());
        request.setRoleId(repairGoodsDO.getParentMemberRoleId());
        request.setMessageNotice(MessageTemplateCode.repair_goods_handle_confirm);
        List<String> params = new ArrayList<>();
        params.add(repairGoodsDO.getApplyNo());
        params.add(repairGoodsDO.getApplyAbstract());
        params.add(RepairGoodsOuterStatusEnum.getMessage(repairGoodsDO.getOuterStatus()));
        request.setParams(params);
        feignService.sendSystemMessage(request);

        return Wrapper.success();
    }

    /**
     * 供应商分页查询等待确认的维修
     * @author 伍将
     * @date 2020/9/2
     * @param user: 当前登录用户
     * @param pageVO:
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.common.response.PageData < com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyQueryVO>>
     **/
    @Override
    public Wrapper<PageData<RepairGoodsQueryVO>> pageToBeConfirm(UserLoginCacheDTO user, RepairGoodsPageBySupplierVO pageVO) {

        // step 1: 组装查询条件
        Specification<RepairGoodsDO> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("parentMemberId").as(Long.class), user.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("parentMemberRoleId").as(Long.class), user.getMemberRoleId()));

            // 查询外部状态为待提交或不接受申请的
            List<Integer> innerStatusList = new ArrayList<>();
            innerStatusList.add(RepairGoodsInnerStatusEnum.VERIFY_STEP2_PASSED.getCode());
            innerStatusList.add(RepairGoodsInnerStatusEnum.VERIFY_STEP2_UN_PASSED.getCode());
            innerStatusList.add(RepairGoodsInnerStatusEnum.VERIFY_STEP1_UN_PASSED.getCode());
            innerStatusList.add(RepairGoodsInnerStatusEnum.SUBMIT_VERIFY_UN_PASSED.getCode());
            list.add(criteriaBuilder.in(root.get("innerStatus")).value(innerStatusList));

            if (StringUtils.hasLength(pageVO.getStartTime())) {
                list.add(criteriaBuilder.greaterThan(root.get("applyTime").as(Long.class), DateUtil.parse(pageVO.getStartTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getEndTime())) {
                list.add(criteriaBuilder.lessThan(root.get("applyTime").as(Long.class), DateUtil.parse(pageVO.getEndTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getApplyNo())) {
                list.add(criteriaBuilder.like(root.get("applyNo").as(String.class), "%" + pageVO.getApplyNo().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getApplyAbstract())) {
                list.add(criteriaBuilder.like(root.get("applyAbstract").as(String.class), "%" + pageVO.getApplyAbstract().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getConsumerName())) {
                list.add(criteriaBuilder.like(root.get("consumerName").as(String.class), "%" + pageVO.getConsumerName().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // step 2: 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("applyTime").descending());

        // step 3: 分页查询数据
        Page<RepairGoodsDO> result = this.repairGoodsRepository.findAll(spec, page);

        // step 4: 组装返回数据
        List<RepairGoodsQueryVO> resultList = convertRepairApplyQueryVO(result.getContent(), true);

        return Wrapper.success(new PageData<>(result.getTotalElements(), resultList));
    }

    /**
     * 新增内部工作流记录
     * @author 伍将
     * @date 2020/12/26
     * @param user: 当前登录用户
     * @param repairId: 维修id
     * @param status: 状态
     * @param statusName: 状态名称
     * @param operate: 操作
     * @param opinion: 意见
     **/
    private void addInnerWorkflowRecord(UserLoginCacheDTO user, Long repairId, Integer status, String statusName, String operate, String opinion) {

        InnerWorkflowRecordDO recordDO = new InnerWorkflowRecordDO();
        recordDO.setAfterSaleId(repairId);
        recordDO.setAfterSaleType(AfterSaleTypeEnum.REPAIR.getCode());
        recordDO.setUserId(user.getUserId());
        recordDO.setMemberId(user.getMemberId());
        recordDO.setRoleId(user.getMemberRoleId());
        recordDO.setOperator(user.getUserName());
        recordDO.setDepartment(user.getUserOrgName());
        recordDO.setJobTitle(user.getUserJobTitle());
        recordDO.setStatus(statusName);
        recordDO.setStatusCode(status);
        recordDO.setOperate(operate);
        recordDO.setOperateTime(System.currentTimeMillis());
        recordDO.setOpinion(opinion);
        innerWorkflowRecordRepository.saveAndFlush(recordDO);
    }

    /**
     * 提交审核
     * @author 伍将
     * @date 2020/9/2
     * @param user:
     * @param verifyVO:
     * @return : com.ssy.lingxi.common.response.Wrapper
     **/
    @Transactional
    @Override
    public Wrapper<Void> submitVerify(UserLoginCacheDTO user, VerifyVO verifyVO) {
        RepairGoodsDO repairGoodsDO = repairGoodsRepository.findById(verifyVO.getApplyId()).orElse(null);
        if (repairGoodsDO == null) {
            throw new BusinessException(ResponseCode.AS_REPAIR_NOT_EXIST);
        }
        // 当选择审核不通过时，审核不通过原因为必填
        if (verifyVO.getIsPass().equals(CommonBooleanEnum.NO.getCode()) && !StringUtils.hasLength(verifyVO.getOpinion())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_VERIFY_OPINION_EMPTY);
        }
        // 外部状态不为待确认时，不允许审核（只有提交的申请才允许审核）
        if (!repairGoodsDO.getOuterStatus().equals(RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_UN_ALLOW_VERIFY);
        }

        // 执行工作流
        repairGoodsDO= completeInnerTask(repairGoodsDO, verifyVO.getIsPass());
        repairGoodsRepository.saveAndFlush(repairGoodsDO);

        String statusName = RepairGoodsInnerStatusEnum.getMessage(repairGoodsDO.getInnerStatus());
        // 新增内部流转记录
        addInnerWorkflowRecord(user, repairGoodsDO.getId(), repairGoodsDO.getInnerStatus(), statusName, RepairGoodsActionEnum.SUBMIT_VALIFY.getMessage(), verifyVO.getOpinion());

        // 售后维修处理待提交审核维修申请单-1,(待审核维修申请单（一级）+1或待确认维修申请单+1)
        OperateNoticeVO noticeVO = new OperateNoticeVO();
        noticeVO.setMemberId(repairGoodsDO.getParentMemberId());
        noticeVO.setRoleId(repairGoodsDO.getParentMemberRoleId());
        noticeVO.setDataSource(OperateDataSourceEnum.AFTER_SALE_REPAIR_HANDLE.getCode());
        noticeVO.setReduceOperateType(AfterSaleRepairHandleOperateTypeEnum.TO_BE_VALIFY_COMMIT.getCode());
        noticeVO.setReduceCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        AfterSaleRepairHandleOperateTypeEnum operateTypeEnum = RepairGoodsInnerStatusEnum.SUBMIT_VERIFY_UN_PASSED.getCode().equals(repairGoodsDO.getInnerStatus())
                ? AfterSaleRepairHandleOperateTypeEnum.TO_BE_CONFIRM : AfterSaleRepairHandleOperateTypeEnum.TO_BE_VALIFY_STEP1;
        noticeVO.setIncreaseOperateType(operateTypeEnum.getCode());
        noticeVO.setIncreaseCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        noticeVO.setIncreaseTitle(repairGoodsDO.getApplyAbstract());
        noticeVO.setIncreaseDataId(repairGoodsDO.getId());
        noticeVO.setReduceDataId(repairGoodsDO.getId());
        feignService.addSysOperateNotice(noticeVO);

        // 新增消息通知
        SystemMessageRequest request = new SystemMessageRequest();
        request.setMemberId(repairGoodsDO.getParentMemberId());
        request.setRoleId(repairGoodsDO.getParentMemberRoleId());
        String messageTemplateCode = MessageTemplateCode.repair_goods_handle_audit_step_1;
        if (RepairGoodsInnerStatusEnum.SUBMIT_VERIFY_UN_PASSED.getCode().equals(repairGoodsDO.getInnerStatus())) {
            messageTemplateCode = MessageTemplateCode.repair_goods_handle_confirm;
        }
        request.setMessageNotice(messageTemplateCode);
        List<String> params = new ArrayList<>();
        params.add(repairGoodsDO.getApplyNo());
        params.add(repairGoodsDO.getApplyAbstract());
        params.add(RepairGoodsOuterStatusEnum.getMessage(repairGoodsDO.getOuterStatus()));
        request.setParams(params);
        feignService.sendSystemMessage(request);


        return Wrapper.success();
    }

    /**
     * 确认审核
     * @author 伍将
     * @date 2020/9/2
     * @param user:
     * @param verifyVO:
     * @return : com.ssy.lingxi.common.response.Wrapper
     **/
    @Override
    public Wrapper<Void> confirmVerify(UserLoginCacheDTO user, VerifyVO verifyVO) {
        RepairGoodsDO repairGoodsDO = repairGoodsRepository.findById(verifyVO.getApplyId()).orElse(null);
        if (repairGoodsDO == null) {
            throw new BusinessException(ResponseCode.AS_REPAIR_NOT_EXIST);
        }
        // 外部状态为待确认，内部状态为二级审核通过或不接受申请时才允许确认审核
        if (!RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode().equals(repairGoodsDO.getOuterStatus())
                || (!RepairGoodsInnerStatusEnum.VERIFY_STEP2_PASSED.getCode().equals(repairGoodsDO.getInnerStatus())
                && !RepairGoodsInnerStatusEnum.VERIFY_STEP2_UN_PASSED.getCode().equals(repairGoodsDO.getInnerStatus())
                && !RepairGoodsInnerStatusEnum.VERIFY_STEP1_UN_PASSED.getCode().equals(repairGoodsDO.getInnerStatus())
                && !RepairGoodsInnerStatusEnum.SUBMIT_VERIFY_UN_PASSED.getCode().equals(repairGoodsDO.getInnerStatus()))
        ) {
            throw new BusinessException(ResponseCode.AS_REPAIR_UN_ALLOW_VERIFY);
        }
        // 当选择审核不通过时，审核不通过原因为必填
        if (verifyVO.getIsPass().equals(CommonBooleanEnum.NO.getCode()) && !StringUtils.hasLength(verifyVO.getOpinion())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_VERIFY_OPINION_EMPTY);
        }
        // 只有内部状态为审核通过的才允许选择接受申请
        if (CommonBooleanEnum.YES.getCode().equals(verifyVO.getIsPass()) && !RepairGoodsInnerStatusEnum.VERIFY_STEP2_PASSED.getCode().equals(repairGoodsDO.getInnerStatus())) {
            throw new BusinessException(ResponseCode.AS_REPAIR_GOODS_UN_ALLOW_VERIFY_ACCEPT);
        }
        //执行内部工作流
        repairGoodsDO= completeInnerTask(repairGoodsDO, verifyVO.getIsPass());
        Integer status = repairGoodsDO.getInnerStatus();
        // 如果内部状态为确认接受申请或确认不接受申请时，设置外部状态
        if (RepairGoodsInnerStatusEnum.CONFIRM_ACCEPT_APPLY.getCode().equals(status)) {
            repairGoodsDO.setOuterStatus(RepairGoodsOuterStatusEnum.ACCEPT_APPLY.getCode());
        } else if (RepairGoodsInnerStatusEnum.CONFIRM_UN_ACCEPT_APPLY.getCode().equals(status)) {
            repairGoodsDO.setOuterStatus(RepairGoodsOuterStatusEnum.UN_ACCEPT_APPLY.getCode());
        }
        repairGoodsRepository.saveAndFlush(repairGoodsDO);

        String statusName = RepairGoodsInnerStatusEnum.getMessage(repairGoodsDO.getInnerStatus());
        // 新增内部流转记录
        addInnerWorkflowRecord(user, repairGoodsDO.getId(), repairGoodsDO.getInnerStatus(), statusName, RepairGoodsActionEnum.CONFIRM.getMessage(), verifyVO.getOpinion());
        // 新增供应商外部工作流记录
        addOuterWorkflowRecord(user, repairGoodsDO.getId(), repairGoodsDO.getOuterStatus(),RepairGoodsOuterStatusEnum.getMessage(repairGoodsDO.getOuterStatus()) , RepairGoodsActionEnum.CONFIRM.getMessage(), verifyVO.getOpinion());

        // 售后维修处理待确认维修申请单-1
        OperateNoticeVO noticeVO = new OperateNoticeVO();
        noticeVO.setMemberId(repairGoodsDO.getParentMemberId());
        noticeVO.setRoleId(repairGoodsDO.getParentMemberRoleId());
        noticeVO.setDataSource(OperateDataSourceEnum.AFTER_SALE_REPAIR_HANDLE.getCode());
        noticeVO.setReduceOperateType(AfterSaleRepairHandleOperateTypeEnum.TO_BE_CONFIRM.getCode());
        noticeVO.setReduceCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        noticeVO.setReduceDataId(repairGoodsDO.getId());
        feignService.addSysOperateNotice(noticeVO);

        // 售后维修申请待确认售后完成+1或待提交+1
        noticeVO = new OperateNoticeVO();
        noticeVO.setMemberId(repairGoodsDO.getMemberId());
        noticeVO.setRoleId(repairGoodsDO.getRoleId());
        noticeVO.setDataSource(OperateDataSourceEnum.AFTER_SALE_REPAIR_APPLY.getCode());
        AfterSaleRepairApplyOperateTypeEnum operateTypeEnum = RepairGoodsInnerStatusEnum.CONFIRM_ACCEPT_APPLY.getCode().equals(status) ?
                AfterSaleRepairApplyOperateTypeEnum.TO_BE_CONFIRM_COMPLETE : AfterSaleRepairApplyOperateTypeEnum.TO_BE_COMMIT;
        noticeVO.setIncreaseOperateType(operateTypeEnum.getCode());
        noticeVO.setIncreaseCount(Constants.SYS_OPERATE_NOTICE_COUNT);
        noticeVO.setIncreaseTitle(repairGoodsDO.getApplyAbstract());
        noticeVO.setIncreaseDataId(repairGoodsDO.getId());
        feignService.addSysOperateNotice(noticeVO);

        // 新增消息通知
        SystemMessageRequest request = new SystemMessageRequest();
        request.setMemberId(repairGoodsDO.getMemberId());
        request.setRoleId(repairGoodsDO.getRoleId());
        if (RepairGoodsOuterStatusEnum.ACCEPT_APPLY.getCode().equals(repairGoodsDO.getOuterStatus())) {
            request.setMessageNotice(MessageTemplateCode.repair_goods_apply_agree);
        } else {
            request.setMessageNotice(MessageTemplateCode.repair_goods_apply_refuse);
        }
        request.setParams(Arrays.asList(repairGoodsDO.getApplyNo(), repairGoodsDO.getApplyAbstract(),repairGoodsDO.getSupplierName()));
        feignService.sendSystemMessage(request);

        return Wrapper.success();
    }

    /**
     * 获取维修详情
     * @author 伍将
     * @date 2020/9/2
     * @param user: 当前登录用户
     * @param repairId: 维修id
     * @param isSupplier: 是否为供应商
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyDetailVO>
     **/
    private Wrapper<RepairGoodsDetailVO> getDetail(UserLoginCacheDTO user, Long repairId, Boolean isSupplier) {

        RepairGoodsDO repairGoodsDO = repairGoodsRepository.findById(repairId).orElse(null);
        if (repairGoodsDO == null) {
            throw new BusinessException(ResponseCode.AS_REPAIR_NOT_EXIST);
        }

        RepairGoodsDetailVO result = new RepairGoodsDetailVO();

        // 组装基础信息
        result.setApplyId(repairGoodsDO.getId());
        result.setApplyNo(repairGoodsDO.getApplyNo());
        result.setApplyAbstract(repairGoodsDO.getApplyAbstract());
        result.setConsumerName(repairGoodsDO.getConsumerName());
        result.setSupplierName(repairGoodsDO.getSupplierName());
        result.setParentMemberId(repairGoodsDO.getParentMemberId());
        result.setParentMemberRoleId(repairGoodsDO.getParentMemberRoleId());
        result.setApplyTime(DateUtil.format(DateUtil.date(repairGoodsDO.getApplyTime()), "yyyy-MM-dd HH:mm"));
        result.setOuterStatus(repairGoodsDO.getOuterStatus());
        result.setOuterStatusName(RepairGoodsOuterStatusEnum.getMessage(repairGoodsDO.getOuterStatus()));
        result.setInnerStatus(repairGoodsDO.getInnerStatus());
        //外部为待确认申请单，消费者内部状态为已提交
        if(RepairGoodsOuterStatusEnum.TO_BE_CONFIRM.getCode().equals(repairGoodsDO.getOuterStatus())&&!isSupplier){
            result.setInnerStatusName(RepairGoodsInnerStatusEnum.SUBMIT_VERIFY_PASSED.getConsumerDescribe());
        }else {
            result.setInnerStatusName(RepairGoodsInnerStatusEnum.getDescribe(repairGoodsDO.getInnerStatus(), isSupplier));
        }
        result.setFaultFileList(repairGoodsDO.getFaultFileList());
        result.setRepairAddress(repairGoodsDO.getRepairAddress());
        result.setOrderType(repairGoodsDO.getOrderType());
        result.setRepaireReason(repairGoodsDO.getRepaireReason());
        result.setShopName(repairGoodsDO.getShopName());
        result.setShopId(repairGoodsDO.getShopId());
        result.setShopLogo(repairGoodsDO.getShopLogo());
        result.setShopName(repairGoodsDO.getShopName());
        // 设置代客标识
        result.setAgentFlag(Optional.ofNullable(repairGoodsDO.getAgentFlag()).orElse(AgentFlagEnum.NOT.getCode()));
        // 组装评价
        Wrapper<EvaluateBO> evaluateWrapper = evaluateService.getDetail(repairId, AfterSaleTypeEnum.REPAIR.getCode());
        if ( evaluateWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(evaluateWrapper);
        }
        result.setEvaluate(evaluateWrapper.getData());

        // 组装外部单据流转记录
        Wrapper<List<RepairOuterWorkflowRecordVO>> outerRecordWrapper = outerWorkflowRecordService.getRepairRecordList(repairId);
        if ( outerRecordWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(outerRecordWrapper);
        }
        result.setOuterRecordList(outerRecordWrapper.getData());

        // 组装外部流转，由于外部流转只有简单的三步，这里自行组装流转
        List<TaskStepVO> outerTaskList = new ArrayList<>();
        //内部流转步骤最大为3
        int outerMaxTaskStep = 3;
        for (int i = 1; i <= outerMaxTaskStep; i++) {
            TaskStepVO taskStepVO = new TaskStepVO();
            taskStepVO.setStep(i);
            if (i == 1) {
                taskStepVO.setRoleName("采购商");
                taskStepVO.setTaskName("提交维修申请单");
            } else if (i == 2) {
                taskStepVO.setRoleName("供应商");
                taskStepVO.setTaskName("确认维修申请单");
            } else {
                taskStepVO.setRoleName("采购商");
                taskStepVO.setTaskName("确认售后完成");
            }
            // 对应外部操作记录存在时，则流转被执行
            if (outerRecordWrapper.getData().stream().filter(o -> o.getStep().equals(taskStepVO.getStep())).findFirst().orElse(null) != null) {
                taskStepVO.setIsExecute(CommonBooleanEnum.YES.getCode());
            } else {
                if (RepairGoodsOuterStatusEnum.UN_ACCEPT_APPLY.getCode().equals(repairGoodsDO.getOuterStatus())
                        || RepairGoodsOuterStatusEnum.ACCEPT_APPLY.getCode().equals(repairGoodsDO.getOuterStatus())
                        || RepairGoodsOuterStatusEnum.COMPLETE.getCode().equals(repairGoodsDO.getOuterStatus())) {
                    taskStepVO.setIsExecute(CommonBooleanEnum.YES.getCode());
                } else {
                    taskStepVO.setIsExecute(CommonBooleanEnum.NO.getCode());
                }
            }

            outerTaskList.add(taskStepVO);
        }
        result.setOuterTaskList(outerTaskList);

        // 组装内部单据流转记录
        Wrapper<List<RepairInnerWorkflowRecordVO>> innerRecordWrapper = innerWorkflowRecordService.getRepairRecordList(user.getMemberId(), user.getMemberRoleId(), repairId);
        if ( innerRecordWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(innerRecordWrapper);
        }
        result.setInnerRecordList(innerRecordWrapper.getData());

        // 组装内部流转
        if(isSupplier) {
            List<TaskStepVO> innerTaskList = processFeignService.listTaskStep(ProcessEnum.AFTER_SALE_REPAIR_INNER_VERIFY.getCode(), repairGoodsDO.getTaskId(), repairGoodsDO.getMemberId());
            result.setInnerTaskList(innerTaskList);
        }

        return Wrapper.success(result);
    }

    /**
     * 消费者获取维修详情
     * @author 伍将
     * @date 2020/9/2
     * @param user: 当前登录用户
     * @param repairId:
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyDetailVO>
     **/
    @Override
    public Wrapper<RepairGoodsDetailVO> getDetailByConsumer(UserLoginCacheDTO user, Long repairId) {
        return getDetail(user, repairId, false);
    }

    /**
     * 供应商获取维修详情
     * @author 伍将
     * @date 2020/9/2
     * @param user: 当前登录用户
     * @param repairId:
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.after.sale.model.vo.repair.response.RepairApplyDetailVO>
     **/
    @Override
    public Wrapper<RepairGoodsDetailVO> getDetailBySupplier(UserLoginCacheDTO user, Long repairId) {
        return getDetail(user, repairId, true);
    }

    /**
     * 分页查询列表页面搜索条件内容
     * @author 伍将
     * @date 2020/10/17
     * @param user: 当前登录用户
     * @return : com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.after.sale.model.vo.response.RepairGoodsPageItemsVO>
     **/
    @Override
    public Wrapper<RepairGoodsPageItemsVO> pageItems(UserLoginCacheDTO user) {

        RepairGoodsPageItemsVO result = new RepairGoodsPageItemsVO();

        // 组装外部状态
        result.setOuterStatusList(convertOuterStatus());
        // 组装内部状态
        result.setInnerStatusList(convertInnerStatus());

        return Wrapper.success(result);
    }

    /**
     * 获取外部状态列表
     * @author 伍将
     * @date 2020/10/17
     * @return : java.util.List<com.ssy.lingxi.after.sale.model.vo.response.PageItemVO>
     **/
    private List<PageItemVO> convertOuterStatus() {
        return Arrays.stream(RepairGoodsOuterStatusEnum.values()).map(r -> {
            PageItemVO status = new PageItemVO();
            status.setStatus(r.getCode());
            status.setName(r.getMessage());
            return status;
        }).collect(Collectors.toList());
    }

    /**
     * 获取内部状态列表
     * @author 伍将
     * @date 2020/10/17
     * @return : java.util.List<com.ssy.lingxi.after.sale.model.vo.response.PageItemVO>
     **/
    private List<PageItemVO> convertInnerStatus() {
        return Arrays.stream(RepairGoodsInnerStatusEnum.values()).map(r -> {
            PageItemVO status = new PageItemVO();
            status.setStatus(r.getCode());
            status.setName(r.getMessage());
            return status;
        }).collect(Collectors.toList());
    }

    /**
     * 平台分页查询维修申请
     * @author 伍将
     * @date 2020/12/7
     * @param user: 当前登录用户
     * @param pageVO:
     * @return :
     **/
    @Override
    public Wrapper<PageData<RepairGoodsQueryVO>> pageByPlatform(UserLoginCacheDTO user, RepairGoodsPageByPlatformVO pageVO) {
        // step 1: 组装查询条件
        Specification<RepairGoodsDO> spec =  (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if (null != pageVO.getOuterStatus() && !RepairGoodsOuterStatusEnum.ALL.getCode().equals(pageVO.getOuterStatus())) {
                list.add(criteriaBuilder.equal(root.get("outerStatus").as(Integer.class), pageVO.getOuterStatus()));
            }
            if (null != pageVO.getInnerStatus() && !RepairGoodsInnerStatusEnum.ALL.getCode().equals(pageVO.getInnerStatus())) {
                list.add(criteriaBuilder.equal(root.get("innerStatus").as(Integer.class), pageVO.getInnerStatus()));
            }
            if (StringUtils.hasLength(pageVO.getStartTime())) {
                list.add(criteriaBuilder.greaterThan(root.get("applyTime").as(Long.class), DateUtil.parse(pageVO.getStartTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getEndTime())) {
                list.add(criteriaBuilder.lessThan(root.get("applyTime").as(Long.class), DateUtil.parse(pageVO.getEndTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getApplyNo())) {
                list.add(criteriaBuilder.like(root.get("applyNo").as(String.class), "%" + pageVO.getApplyNo().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getApplyAbstract())) {
                list.add(criteriaBuilder.like(root.get("applyAbstract").as(String.class), "%" + pageVO.getApplyAbstract().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getConsumerName())) {
                list.add(criteriaBuilder.like(root.get("consumerName").as(String.class), "%" + pageVO.getConsumerName().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getSupplierName())) {
                list.add(criteriaBuilder.like(root.get("supplierName").as(String.class), "%" + pageVO.getSupplierName().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // step 2: 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("applyTime").descending());

        // step 3: 分页查询数据
        Page<RepairGoodsDO> result = this.repairGoodsRepository.findAll(spec, page);

        // step 4: 组装返回数据
        List<RepairGoodsQueryVO> resultList = convertRepairApplyQueryVO(result.getContent(), false);

        return Wrapper.success(new PageData<>(result.getTotalElements(), resultList));
    }

    /**
     * 平台查询维修申请详情
     * @author 伍将
     * @date 2020/12/7
     * @param user: 当前登录用户
     * @param repairId:
     * @return :
     **/
    @Override
    public Wrapper<RepairGoodsDetailVO> getDetailByPlatform(UserLoginCacheDTO user, Long repairId) {
        return getDetail(user, repairId, false);
    }

    /**
     * 执行内部工作流
     * @param entity 售后维修数据
     * @param agree 执行人
     * @return 执行结果
     */
    public RepairGoodsDO completeInnerTask(RepairGoodsDO entity, Integer agree){
        TaskExecuteVO taskStartVO=new TaskExecuteVO();
        taskStartVO.setProcessKey(ProcessEnum.AFTER_SALE_REPAIR_INNER_VERIFY.getProcessKey());
        taskStartVO.setMemberId(entity.getMemberId());
        taskStartVO.setRoleId(entity.getRoleId());
        taskStartVO.setDataId(entity.getId());
        taskStartVO.setAgree(agree);
        taskStartVO.setTaskId(entity.getTaskId());
        Wrapper<SimpleTaskCompleteVO> taskResult = processFeignService.completeSimpleTask(taskStartVO);
        if (taskResult == null || taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            throw new BusinessException(ResponseCode.AS_WORKFLOW_ERROR);
        }
        entity.setInnerStatus(taskResult.getData().getStatus());
        String taskId=taskResult.getData().getTaskId();
        entity.setTaskId(StringUtils.hasLength(taskId)?taskId:Constants.WORK_FLOW_END_TASK_ID_TAG);
        entity.setInnerTaskStep(taskResult.getData().getStep());
        entity.setUpdateTime(System.currentTimeMillis());
        return entity;
    }
}
